package com.test;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

import com.hsmpay.utils.DesUtil;
import com.hsmpay.utils.JSONStringBuilder;
import net.sf.json.JSONObject;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

public class Demo {
	public String url = "http://180.168.27.30:30400/credit_card/pay";
	public String yanqian_url = "http://180.168.27.30:30400/auth/card";
	public String companyId ="16000251";
	public String chaxun_url = "http://180.168.27.30:30400/credit_card/query";
	public String auth_card_query_url = "http://180.168.27.30:30400/auth/card_quey";
	public String key3des = "JR9xoQr7RblhHrUIgDA8Oci/01NsENJggEeTuc5DFPPk/AbjPRDjH5vukQm0+DwpjXCvbKoLZx7iVBqxUoX/FsGniW4L8qgeXuk3BI0eHchcUsGWQj3xVuSIS856+1WthM7sqVopZ3Hrul3onjCv+q3R6jYML2KI34dVofJfLgzifCrd3rlKBT6qDL7yE3SokPxDpkQHMPvux9NPkSvkI2z49NPbsaYRU2agB49gaDwEsCtnninhtI2KM5OHps+3sEHIj1BxvNvZzqn9LwmGAMW6+9Z7QFb/If3BGDYd8PQUJdTQoddyxy7eYwnQNS49pXQhj0MOdHqiXu2aFfaRtQ==";

	/**
	 * 无卡支付测试
	 * @throws UnsupportedEncodingException
     */
	//@Test
	public void pay() throws UnsupportedEncodingException {
		TreeMap<String,String> parameterMap = new TreeMap<String,String>();
		parameterMap.put("amount", "1");
		parameterMap.put("cardno", "6225768719817221");
		parameterMap.put("idcardtype", "01");
		parameterMap.put("idcard", "350583198906231310");
		parameterMap.put("owner", "李诗杰");
		parameterMap.put("currency", "156");
		parameterMap.put("cvv2", "197");
		parameterMap.put("usercode", String.valueOf(System.currentTimeMillis()));
		//parameterMap.put("identitytype", "01");//
		parameterMap.put("companyid", companyId);
		parameterMap.put("orderid", "hsm"+String.valueOf(System.currentTimeMillis()));
		parameterMap.put("phone", "18611585560");
		parameterMap.put("productcode", "1");
		parameterMap.put("productdesc", "花生米测试数据");
		parameterMap.put("productname", "花生米测试数据");
		parameterMap.put("transtime", String.valueOf(System.currentTimeMillis()));
		parameterMap.put("userip", "172.18.66.218");
		parameterMap.put("validthru", "0416");
		parameterMap.put("sign", getSign(parameterMap));

		String paramStr = JSONStringBuilder.getAjaxString(parameterMap);
		System.out.println("发送的报文明文为: " + paramStr);
		paramStr = DesUtil.encryptThreeDES(paramStr.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		paramStr = companyId + "," + paramStr;
		System.out.println("发送的报文加密结果为: " + paramStr);
		String result = HttpClientUtil.httpPostWithJSON(url, paramStr);

		result = result.split(",")[1];
		System.out.println("返回的报文加密结果为: " + result);
		//back = "2e104016c8e19cef";
		//String result = DesUtil.decryptThreeDES(back.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		result = decode3DES(result,"11223f588810303828257951cbdd556677297398303036e2");
		System.out.println("返回的报文明文结果为: " + result);
		boolean res = Verify(result);

		System.out.println("验签的结果为: " + res);
		
	}

	/**
	 * 交易查询接口
	 * @throws UnsupportedEncodingException
     */
	//@Test
	public void testJiaoyiChaxun() throws UnsupportedEncodingException {
		TreeMap<String,String> parameterMap = new TreeMap<String,String>();
		parameterMap.put("companyid", companyId);
		parameterMap.put("orderid", "12345611380869017521606");
		parameterMap.put("sign", getSign(parameterMap));
		String paramStr = JSONStringBuilder.getAjaxString(parameterMap);
		System.out.println("发送的报文明文为: " + paramStr);
		paramStr = DesUtil.encryptThreeDES(paramStr.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		paramStr = companyId + "," + paramStr;
		System.out.println("发送的报文加密结果为: " + paramStr);
		String result = HttpClientUtil.httpPostWithJSON(chaxun_url, paramStr);

		result = result.split(",")[1];
		System.out.println("返回的报文加密结果为: " + result);
		//back = "2e104016c8e19cef";
		//String result = DesUtil.decryptThreeDES(back.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		result = decode3DES(result,"11223f588810303828257951cbdd556677297398303036e2");
		System.out.println("返回的报文明文结果为: " + result);
		boolean res = Verify(result);

		System.out.println("验签的结果为: " + res);
	}



	private String getSign(TreeMap<String,String> map){

		String sign = treeMapToString(map);
		String privateKeyPath ="src/main/java/com/test/pkcs8_rsa_private_key.pem";
		String publicKeyPath ="src/main/java/com/test/public_key.pem";
		RSAUtils.initKey(privateKeyPath, publicKeyPath);
		RSAUtils utils = new RSAUtils();
		String result = utils.sign(sign);
		return result;

	}
	/**
	 * 鉴权接口
	 */
	//@Test
	public void verify() throws UnsupportedEncodingException {
		TreeMap<String,String> parameterMap = new TreeMap<String,String>();
		String companyid = "16000251";
		String requestId = String.valueOf(System.currentTimeMillis());

		parameterMap.put("companyid", companyid); // 企业账户号

		parameterMap.put("requestid", requestId+"0000003"); // 请求流水号
		parameterMap.put("cardtype", "2");   // 卡折类型
		parameterMap.put("accno", "6225768719817221");         // 账户号
		parameterMap.put("accname", "李诗杰");    // 账户名
		parameterMap.put("idcardtype", "01");// 证件类型  01身份证
		parameterMap.put("idcard", "350583198906231310");// 证件号
		parameterMap.put("phone", "18611585560");//预留手机号
		parameterMap.put("orderid", requestId);//客户订单号  20
		parameterMap.put("transtime", getCurrentTimeNumber());//交易时间  年月日时 如：20160108100000

		//加签过程
		parameterMap.put("sign", getSign(parameterMap));//签名

		String paramStr = JSONStringBuilder.getAjaxString(parameterMap);
		System.out.println("发送的报文明文为: " + paramStr);
		paramStr = DesUtil.encryptThreeDES(paramStr.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		paramStr = companyId + "," + paramStr;
		System.out.println("发送的报文加密结果为: " + paramStr);
		String result = HttpClientUtil.httpPostWithJSON(yanqian_url, paramStr);

		result = result.split(",")[1];
		System.out.println("返回的报文加密结果为: " + result);
		//back = "2e104016c8e19cef";
		//String result = DesUtil.decryptThreeDES(back.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		result = decode3DES(result,"11223f588810303828257951cbdd556677297398303036e2");
		System.out.println("返回的报文明文结果为: " + result);
		boolean res = Verify(result);

		System.out.println("验签的结果为: " + res);

	}
	
	/**
	 * 鉴权接口 查询
	 */
	//@Test
	public void verify_query() throws UnsupportedEncodingException {
		TreeMap<String,String> parameterMap = new TreeMap<String,String>();
		String companyid = "16000251";
		String requestId = String.valueOf(System.currentTimeMillis());

		parameterMap.put("companyid", companyid); // 企业账户号

		parameterMap.put("requestid", requestId+"0000003"); // 请求流水号
		parameterMap.put("cardtype", "2");   // 卡折类型
		parameterMap.put("accno", "6225768719817221");         // 账户号
		parameterMap.put("accname", "李诗杰");    // 账户名
		parameterMap.put("idcardtype", "01");// 证件类型  01身份证
		parameterMap.put("idcard", "350583198906231310");// 证件号
		parameterMap.put("phone", "18611585560");//预留手机号
		parameterMap.put("orderid", requestId);//客户订单号  20
		parameterMap.put("transtime", getCurrentTimeNumber());//交易时间  年月日时 如：20160108100000

		//加签过程
		parameterMap.put("sign", getSign(parameterMap));//签名

		String paramStr = JSONStringBuilder.getAjaxString(parameterMap);
		System.out.println("发送的报文明文为: " + paramStr);
		paramStr = DesUtil.encryptThreeDES(paramStr.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		paramStr = companyId + "," + paramStr;
		System.out.println("发送的报文加密结果为: " + paramStr);
		String result = HttpClientUtil.httpPostWithJSON(yanqian_url, paramStr);

		result = result.split(",")[1];
		System.out.println("返回的报文加密结果为: " + result);
		//back = "2e104016c8e19cef";
		//String result = DesUtil.decryptThreeDES(back.getBytes("UTF-8"), "11223f588810303828257951cbdd556677297398303036e2");
		result = decode3DES(result,"11223f588810303828257951cbdd556677297398303036e2");
		System.out.println("返回的报文明文结果为: " + result);
		boolean res = Verify(result);

		System.out.println("验签的结果为: " + res);

	}
	/**
	 * 返回当前时间的数字
	 *
	 * @return 返回当前时间的数字
	 */
	public static String getCurrentTimeNumber() {
		return new SimpleDateFormat("yyyyMMddHHmmss")
				.format(new java.util.Date());
	}

	/**
	 * 3DES解密
	 * @param dataS 待解密数�?
	 * @param keys 密钥
	 * @return byte[] 解密数据
	 */
	public String decode3DES(String dataS, String keys){
		String result="";
		try {
			byte[] data=DesUtil.hexStringToByte(dataS);
			byte[] key=DesUtil.hexStringToByte(keys);
			Cipher cipher = Cipher.getInstance("DESede");
			DESedeKeySpec dks = new DESedeKeySpec(key);
			SecretKey k = SecretKeyFactory.getInstance("DESede")
					.generateSecret(dks);
			cipher.init(Cipher.DECRYPT_MODE, k);
			byte[] src = cipher.doFinal(data);
			result = new String(src, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("" + e);
		}
		return result;
	}

	public boolean Verify(String jsonStr){
		TreeMap<String, String> treeMap = new TreeMap<String,String>();

		JSONObject json = JSONObject.fromObject(jsonStr);
		for(Object k : json.keySet()){
			String v = (String) json.get(k);
			if (!"sign".equals(k.toString())){
				treeMap.put(k.toString(), v);
			}
		}
		treeMap.put("errorcode","");
		treeMap.put("errormsg","");
		//验签的字符串
		String plaintext = treeMapToString(treeMap);
		System.out.println("验签的字符串为: " + plaintext);
		//验签的签
		String sign = (String) json.get("sign");
		System.out.println("验签的字符串为: " + sign);
		RSAUtils utils = new RSAUtils();
		String privateKeyPath ="src/main/java/com/test/pkcs8_rsa_private_key.pem";
		String publicKeyPath ="src/main/java/com/test/uinpay_abc_public_key_2048.pem";
		RSAUtils.initKey(privateKeyPath, publicKeyPath);
		return utils.verify(plaintext ,sign);
	}

	/**
	 * 将map拼接成所需的字符串
	 * @param treeMap
	 * @return
     */
	public String treeMapToString(TreeMap<String,String> treeMap){
		StringBuffer buffer = new StringBuffer(206);
		Iterator<String> iterator = treeMap.keySet().iterator();
		String key = null, value = null;
		while(iterator.hasNext()){
			key = iterator.next();
			value = treeMap.get(key);
			buffer.append(key).append("=");
			if (null != value){
				buffer.append(value);
			}
		}
		return buffer.toString();
	}

}
